package handlers

import (
	"night-school-api/models"
	"night-school-api/utils"
	"night-school-api/database"
	"night-school-api/middlewares"

	"os"
	"strconv"
	"time"
	"fmt"
	"net/http"

	"github.com/labstack/echo/v4"
)

type Response struct {
	UserInfo models.User `json:"user_info"`
}

type refreshLoginResponse struct {
	Token 	string	`json:"token"`
	UserInfo models.User `json:"user_info"`
}

func UpdateProfile(c echo.Context) error {
	uid := c.Get("uid").(int)

	var req models.User

	// 解析 JSON 请求
	if err := c.Bind(&req); err != nil {
		return utils.JSONError(c, "参数错误")
	}

	if err := c.Validate(&req); err != nil {
		return err
	}

	db := database.DB

	var user models.User
	db.Model(&models.User{}).First(&user, uid)
	if user.ID <= 0 {
		return utils.JSONError(c, "系统错误，请退出重新登录")
	}

	rs := db.Model(&models.User{}).Where("id = ?", user.ID).Updates(map[string]interface{}{
		"name":        req.Name,
		"gender":      req.Gender,
		"age":         req.Age,
		"professtion": req.Professtion,
	})

	// 重新查询一遍
	db.Model(&models.User{}).First(&user, uid)

	if rs.Error != nil {
		return utils.JSONError(c, "修改失败")
	} else {
		var res Response
		res.UserInfo = user
		return utils.JSONSuccess(c, res, "修改成功")
	}
}

// 上传头像
func UploadAvatar(c echo.Context) error {
	uid := c.Get("uid").(int)

	// Source
	file, err := c.FormFile("file")
	if err != nil {
		return utils.JSONError(c, "上传头像失败，未上传文件")
	}

	// Validate image
	isValid, err := utils.IsValidImage(file)
	if !isValid {
		return utils.JSONError(c, "上传头像失败，图片文件格式不正确 ")
	}

	// Destination
	s := strconv.Itoa(uid) + " " + strconv.FormatInt(time.Now().Unix(), 10)
	dstFilename := utils.SubdirFilepath(s, "./uploads/avatar/", file.Filename)

	// c.Logger().Info("dstFilename:" + dstFilename)
	// c.Logger().Info("file.Filename:" + file.Filename)

	src, err := file.Open()
	if err != nil {
		return utils.JSONError(c, "上传头像失败: "+"Failed to open file")
	}
	defer src.Close()

	dst, err := os.Create(dstFilename)
	if err != nil {
		return utils.JSONError(c, "上传头像失败: "+"Failed to create file")
	}
	defer dst.Close()

	if _, err = dst.ReadFrom(src); err != nil {
		return utils.JSONError(c, "上传头像失败: "+"Failed to save file")
	}

	err = utils.ResizeImage(dstFilename, 200, 200)
	if err != nil {
		c.Logger().Info("上传头像失败: " + err.Error())
		return utils.JSONError(c, "上传头像失败: ")
	}

	// 去除路径前缀 uploads
	// c.Logger().Info("dstFilename:" + dstFilename)
	avatar := utils.TrimTopParentPath(dstFilename)
	// c.Logger().Info("avatar:" + avatar)

	db := database.DB

	avatarMap := map[string]interface{}{}
	db.Model(&models.User{}).Select("avatar").First(&avatarMap, uid)
	c.Logger().Info(fmt.Sprintf("avatarMap: %#v", avatarMap))
	oldAvatar, ok := avatarMap["avatar"].(string)
	if !ok {
		oldAvatar = ""
	}


	rs := db.Model(&models.User{}).Where("id = ?", uid).Update("avatar", avatar)
	if rs.Error != nil {
		c.Logger().Info("更新用户头像信息失败: " + rs.Error.Error())
		return utils.JSONError(c, "更新用户头像信息失败")
	}

	// 删除旧的头像文件
	if oldAvatar != "" {
		oldAvatarPath := "./uploads/" + oldAvatar
		// c.Logger().Info("oldAvatarPath: " + oldAvatarPath)
		err := os.Remove(oldAvatarPath)
		if err != nil {
			c.Logger().Info("删除旧的头像文件失败: " + err.Error())
		}
	}

	var user models.User
	db.Model(&models.User{}).First(&user, uid)
	var res Response
	res.UserInfo = user

	return utils.JSONSuccess(c, res, "上传头像成功")
}


// 刷新token，并返回用户信息
func RefreshLogin(c echo.Context) error {
	uid := c.Get("uid").(int)

	db := database.DB

	var token string
	var user models.User
	db.Model(&models.User{}).First(&user, uid)
	if user.ID <= 0 {
		token = ""
	}

	token, err := middlewares.GenerateToken(uid, "user")
	if err != nil {	
		token = ""
	}

	if token == "" {
		return c.JSON(http.StatusUnauthorized, map[string]interface{}{
			"code": http.StatusUnauthorized,
			"msg": "系统错误，请退出重新登录",
			"data": nil,
		})
	} else {
		var res refreshLoginResponse
		res.Token = token
		res.UserInfo = user

		return utils.JSONSuccess(c, res, "刷新登录成功")
	}

}